package com.colbert.jknife.handler;

import com.colbert.jknife.annotation.AnnotationType;
import com.colbert.jknife.annotation.OnClick;
import com.colbert.jknife.model.Constant;
import com.colbert.jknife.model.FieldCodeSet;
import com.colbert.jknife.model.ICodeSetManager;
import com.squareup.javapoet.CodeBlock;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;

@AnnotationType(OnClick.class)
public class OnClickAnnotationHandler extends BaseAnnotationHandler {

    @Override
    public boolean checkElement(Element element) {
        if(!(element instanceof ExecutableElement)) {
            error(String.format("@%s can only be used in methods.", OnClick.class.getSimpleName()), element);
            return false;
        }
        return true;
    }

    @Override
    public void makeFieldCodeSet(Element element, ICodeSetManager codeSetManager) throws Exception {
        OnClick annotation = element.getAnnotation(OnClick.class);
        ExecutableElement methodElement = (ExecutableElement) element;
        String className = getClassName(element);
        for (int id : annotation.value()) {
            FieldCodeSet fieldCodeSet = codeSetManager.getOrCreateFieldCodeSet(className, id);
            checkFieldBlock(fieldCodeSet, id);
            CodeBlock.Builder builder = CodeBlock.of("$L.$L(new $T() { ", Constant.VIEW_LITERAL, Constant.SET_ONCLICK_LISTENER_LITERAL, getTypeName(Constant.CLASS_ONCLICK_LISTENER)).toBuilder();
            addIntent(builder);
            builder.add(CodeBlock.of("$L($T $L) {", Constant.ONCLICK_METHOD_LITERAL, getTypeName(Constant.CLASS_VIEW), Constant.VIEW_LITERAL));
            addIntent(builder);
            builder.add(CodeBlock.of("$L.$N($L);", Constant.TARGET, methodElement.getSimpleName(), Constant.VIEW_LITERAL));
            subIntent(builder);
            builder.add(CodeBlock.of("}"));
            subIntent(builder);
            builder.add(CodeBlock.of("});"));
            fieldCodeSet.addMethodCodeBlock(builder.build());
        }
    }

    public String getClassName(Element element) {
        TypeElement typeElement = (TypeElement) element.getEnclosingElement();
        return typeElement.getQualifiedName().toString();
    }
}
